From justin: add writing to coastexp.c
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Thu, 11 Nov 2004 20:33:14 +0000 (20:33 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Thu, 11 Nov 2004 20:33:14 +0000 (20:33 +0000)
gpsbabel/Makefile
gpsbabel/coastexp.c
gpsbabel/reference/coastexp.ref
gpsbabel/testo
gpsbabel/xmlgeneric.c

index 70820dc64a33e68fc06bdeac23306c8e5ebca7b9..ecf6750e66c523737461b655d0725acc340d8a2d 100644 (file)
@@ -45,7 +45,7 @@ COLDSYNC=coldsync/util.o coldsync/pdb.o
 SHAPE=shapelib/shpopen.o shapelib/dbfopen.o
 
 LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \
-          csv_util.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \
+          csv_util.o grtcirc.o vmem.o util_crc.o xmlgeneric.o uuid.o \
        $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(FMTS) $(FILTERS)
 OBJS = main.o $(LIBOBJS)
 
@@ -166,6 +166,7 @@ mapsend.o: mapsend.c defs.h queue.h mapsend.h magellan.h
 mapsource.o: mapsource.c defs.h queue.h garmin_tables.h
 mkshort.o: mkshort.c defs.h queue.h
 navicache.o: navicache.c defs.h queue.h
+coastexp.o: coastexp.c defs.h queue.h
 netstumbler.o: netstumbler.c defs.h queue.h csv_util.h
 nmea.o: nmea.c defs.h queue.h
 ozi.o: ozi.c defs.h queue.h csv_util.h
index b8e19ecdc1968a92000c49e149609633b96ed268..aa8aaf0a4bd9aa10bedf328c6d1ab0980b0b161e 100755 (executable)
 #include <expat.h>
 static XML_Parser psr;
 #endif
+#include <time.h>
+
+#include "uuid.h"
 
 FILE *fd;
 FILE *ofd;
 
 #define MYNAME "coastexp"
 #define MY_CBUF 4096
+#define MY_TBUF 64
+#define MY_UBUF 128
 
 #if NO_EXPAT
 void
@@ -42,107 +47,114 @@ ce_read(void)
 }
 #else
 
+static void *mkshort_handle; // short-name handle
 static char *element; // Current element being parsed
 static char *cdatastr; // Current XML character data being built up (until a <lf>)
 
 /* CE-specific mark structure - used for both route marks and standalone marks */
 struct CE_MARK {
-       struct CE_MARK *next;   // pointer to next mark in list
+       queue Q;
        char *id;               // CE's mark ID (of the form "{<guid>}")
-       waypoint *wp;           // GPSBabel waypoint
+       char *created;  // CE's creation time (of the form "<YYYY><MM><DD>T<HH><MM><SS>Z")
+       waypoint *wp;   // GPSBabel waypoint
        int used;               // Is this mark used in a route or not?
 };
 typedef struct CE_MARK ce_mark;
 
 /* CE-specific route structure */
 struct CE_ROUTE {
-       struct CE_ROUTE *next;  // pointer to next route in list
-       char *id;               // CE's route ID (of the form "{<guid>}")
+       queue Q;
+       char *id;                       // CE's route ID (of the form "{<guid>}")
        route_head *r;          // GPSBabel route header
-       ce_mark *marks;         // list of CE marks in this route
+       queue ce_mark_head;     // list of CE marks in this route
 };
 typedef struct CE_ROUTE ce_route;
 
-static ce_route *routes = NULL;                // List of routes currently found
+static queue ce_route_head;                            // List of routes currently found
 static ce_route *currentRoute = NULL;  // Current route being processed
-static ce_mark *marks = NULL;          // List of stand-alone marks currently found
-static ce_mark *currentMark = NULL;    // Current mark being processed
-static int inRoute = 0;                        // Are we processing a route?
-static int inMark = 0;                 // Are we processing a mark?
+static queue ce_mark_head;                             // List of stand-alone marks currently found
+static ce_mark *currentMark = NULL;            // Current mark being processed
+static char *time_buffer = NULL;               // Time buffer for processing times
+static char *uuid_buffer = NULL;               // UUID buffer for processing uuid's
+static int inRoute = 0;                                        // Are we processing a route?
+static int inMark = 0;                                 // Are we processing a mark?
 
 /* Add a route to the list of routes */
 static void
 add_route(ce_route *route)
 {
-       if (routes == NULL) {
-               routes = route;
-       } else {
-               ce_route *curr = routes;
-               while (curr->next != NULL)
-                       curr = curr->next;
-               curr->next = route;
-       }
+       ENQUEUE_TAIL(&ce_route_head, &route->Q);
 }
 
 /* Add a mark to the list of stand-alone marks */
 static void
 add_mark(ce_mark *mark)
 {
-       if (marks == NULL) {
-               marks = mark;
-       } else {
-               ce_mark *curr = marks;
-               while (curr->next != NULL)
-                       curr = curr->next;
-               curr->next = mark;
-       }
+       ENQUEUE_TAIL(&ce_mark_head, &mark->Q);
 }
 
 /* Add a mark to the specified route */
 static void
 add_mark_to_route(ce_route *route, ce_mark *mark)
 {
-       if (route->marks == NULL) {
-               route->marks = mark;
-       } else {
-               ce_mark *curr = route->marks;
-               while (curr->next != NULL)
-                       curr = curr->next;
-               curr->next = mark;
+       ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q);
+}
+
+/* Free a mark */
+static void
+free_mark(ce_mark *mark)
+{
+       xfree(mark->id);
+       if (mark->created)
+               xfree(mark->created);
+       xfree(mark);
+}
+
+/* Free a route */
+static void
+free_route(ce_route *route)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               free_mark(mark);
        }
+       xfree(route->id);
+       xfree(route);
+       // Don't free the waypoint since this is done elsewhere
 }
 
 /* Start processing an XML item */
 static void
 ce_start(void *data, const char *el, const char **attr)
 {
-       element = xstrdup(el);
+       const char **ap;
+       strcpy(element, el);
        if (0 == strcmp(el, "Route")) {
                inRoute = 1;
-               const char **ap;
                for (ap = attr; *ap; ap+=2) {
                        if (0 == strcmp(ap[0], "id")) {
                                // Create a CE route object and add it to the list of routes
                                currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1);
-                               currentRoute->next = NULL;
                                currentRoute->id=xstrdup(ap[1]);
                                currentRoute->r = route_head_alloc();
-                               currentRoute->marks = NULL;
+                               QUEUE_INIT(&currentRoute->ce_mark_head);
                                add_route(currentRoute);
                        }
                }
        } else if (0 == strcmp(el, "Mark")) {
                inMark = 1;
-               const char **ap;
+               currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
+               currentMark->wp = NULL;
+               currentMark->used = 0;
+               add_mark(currentMark);
                for (ap = attr; *ap; ap+=2) {
                        if (0 == strcmp(ap[0], "id")) {
                                // Create a CE mark object and add it to the list of stand-alone marks
-                               currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
-                               currentMark->next = NULL;
-                               currentMark->id=xstrdup(ap[1]);
-                               currentMark->wp = NULL;
-                               currentMark->used = 0;
-                               add_mark(currentMark);
+                               currentMark->id = xstrdup(ap[1]);
+                       }
+                       else if (0 == strcmp(ap[0], "created")) {
+                               currentMark->created = xstrdup(ap[1]);
                        }
                }
        }
@@ -163,12 +175,13 @@ static void
 ce_cdata(void *dta, const XML_Char *s, int len)
 {
        if (*s != '\n') {
+               char *edatastr;
                // We buffer up characters in 'cdatastr' until a single <lf> is received
                if ((strlen(cdatastr) + len) > MY_CBUF) {
                        printf("Buffer overflow - line too long!");
                        exit(-1);
                }
-               char *edatastr = cdatastr+strlen(cdatastr);
+               edatastr = cdatastr+strlen(cdatastr);
                memcpy(edatastr, s, len);
                edatastr[len] = '\0';
        } else {
@@ -179,52 +192,90 @@ ce_cdata(void *dta, const XML_Char *s, int len)
                if (strlen(s) <= 0)
                        return;
                if (0 == strcmp(element, "Marks")) {
-                       if (inRoute == 1) {
+                       if (inRoute) {
                                // We are processing the marks in a route so create a CE mark object
                                // and add it to the current route
                                ce_mark *mark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
-                               mark->next = NULL;
                                mark->id = xstrdup(s);
+                               mark->created = NULL;
                                mark->wp = NULL;
                                add_mark_to_route(currentRoute, mark);
                        }
                } else if (0 == strcmp(element, "Position")) {
-                       if (inMark == 1) {
+                       if (inMark) {
                                // We are processing a standalone mark so read the lat/long position
                                // and create a waypoint to add to the current mark
                                char *position = xstrdup(s);
                                char *lat = position;
                                char *latNorS = position;
+                               char *lng;
+                               char *longEorW;
                                while (*latNorS != ' ')
                                        latNorS++;
                                *latNorS++ = '\0';
-                               char *lng = latNorS;
+                               lng = latNorS;
                                lng++; lng++;
-                               char *longEorW = lng;
+                               longEorW = lng;
                                while (*longEorW != ' ')
                                        longEorW++;
                                *longEorW++ = '\0';
-                               currentMark->wp = waypt_new();
+                               if (!currentMark->wp)
+                                       currentMark->wp = waypt_new();
                                currentMark->wp->latitude = atof(lat);
                                if (*latNorS == 'S')
                                        currentMark->wp->latitude = -currentMark->wp->latitude;
                                currentMark->wp->longitude = atof(lng);
                                if (*longEorW == 'W')
                                        currentMark->wp->longitude = -currentMark->wp->longitude;
+                               xfree(position);
                        }
                } else if (0 == strcmp(element, "Name")) {
                        // Names we care about may be either for routes or marks
-                       char *name = xstrdup(s);
-                       if (inMark == 1)
-                               currentMark->wp->shortname = name;
-                       else if (inRoute == 1)
-                               currentRoute->r->rte_name = name;
+                       if (inMark)
+                       {
+                               if (!currentMark->wp)
+                                       currentMark->wp = waypt_new();
+                               currentMark->wp->shortname = xstrdup(s);
+
+                               // Also set the creation time
+                               if (currentMark->created)
+                               {
+                                       struct tm t;
+                                       char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3];
+                                       memset(&t, 0, sizeof(struct tm));
+                                       strncpy(yearString, currentMark->created, 4);
+                                       yearString[4] = '\0';
+                                       t.tm_year = atoi(yearString) - 1900;
+                                       strncpy(monthString, currentMark->created+4, 2);
+                                       monthString[3] = '\0';
+                                       t.tm_mon = atoi(monthString) - 1;
+                                       strncpy(dayString, currentMark->created+6, 2);
+                                       dayString[3] = '\0';
+                                       t.tm_mday = atoi(dayString);
+                                       strncpy(hourString, currentMark->created+9, 2);
+                                       hourString[3] = '\0';
+                                       t.tm_hour = atoi(hourString);
+                                       strncpy(minString, currentMark->created+11, 2);
+                                       minString[3] = '\0';
+                                       t.tm_min = atoi(minString);
+                                       strncpy(secString, currentMark->created+13, 2);
+                                       secString[3] = '\0';
+                                       t.tm_sec = atoi(secString);
+                                       currentMark->wp->creation_time = mktime(&t);
+                               }
+                       }
+                       else if (inRoute)
+                               currentRoute->r->rte_name = xstrdup(s);
                } else if (0 == strcmp(element, "Description")) {
                        // Descriptions we care about may be either for routes or marks
                        char *desc = xstrdup(s);
-                       if (inMark == 1)
+                       if (inMark)
+                       {
+                               if (!currentMark->wp)
+                                       currentMark->wp = waypt_new();
                                currentMark->wp->description = desc;
-                       else if (inRoute == 1)
+                       }
+                       else if (inRoute)
                                currentRoute->r->rte_desc = desc;
                }
 
@@ -238,6 +289,8 @@ void
 ce_rd_init(const char *fname)
 {
        fd = xfopen(fname, "r", MYNAME);
+       QUEUE_INIT(&ce_route_head);
+       QUEUE_INIT(&ce_mark_head);
 
        psr = XML_ParserCreate(NULL);
        if (!psr) {
@@ -246,6 +299,7 @@ ce_rd_init(const char *fname)
 
        XML_SetElementHandler(psr, ce_start, ce_end);
        cdatastr = xcalloc(MY_CBUF,1);
+       element = xcalloc(MY_CBUF,1);
        XML_SetCharacterDataHandler(psr, ce_cdata);
 }
 
@@ -273,22 +327,22 @@ ce_read(void)
 void
 ce_fix_waypoints(void)
 {
-       ce_route *route = routes;
-       while (route != NULL) {
-               ce_mark *mark = route->marks;
-               while (mark != NULL) {
-                       ce_mark *mark2 = marks;
-                       while (mark2 != NULL) {
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               ce_route *route = (ce_route *) elem;
+               queue *elem2, *tmp2;
+               QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) {
+                       ce_mark *mark = (ce_mark *) elem2;
+                       queue *elem3, *tmp3;
+                       QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) {
+                               ce_mark *mark2 = (ce_mark *) elem3;
                                if (0 == strcmp(mark->id, mark2->id)) {
-                                       mark->wp = mark2->wp;
+                                       mark->wp = waypt_dupe(mark2->wp);
                                        mark2->used = 1;
                                        break;
                                }
-                               mark2 = mark2->next;
                        }
-                       mark = mark->next;
                }
-               route = route->next;
        }
 }
 
@@ -296,19 +350,16 @@ ce_fix_waypoints(void)
 void
 ce_check_route_names(void)
 {
-       ce_route *route = routes;
-       while (route != NULL) {
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               ce_route *route = (ce_route *) elem;
                if (route->r->rte_name == NULL) {
-                       cdatastr = '\0';
-                       strcat(cdatastr, marks->wp->shortname);
+                       *cdatastr = '\0';
+                       strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname);
                        strcat(cdatastr, "->");
-                       ce_mark *mark = route->marks;
-                       while (mark->next != NULL)
-                               mark = mark->next;
-                       strcat(cdatastr, mark->wp->shortname);
+                       strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname);
                        route->r->rte_name = xstrdup(cdatastr);
                }
-               route = route->next;
        }
 }
 
@@ -316,18 +367,16 @@ ce_check_route_names(void)
 void
 ce_remove_unused_marks(void)
 {
-       ce_mark *mark = marks;
-       ce_mark *prev_mark = NULL;
-       while (mark != NULL) {
-               if (mark->used == 1) {
-                       if (prev_mark == NULL)
-                               marks = mark = mark->next;
-                       else
-                               prev_mark->next = mark = mark->next;
-                       continue;
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               if (mark->used)
+               {
+                       dequeue(elem);
+                       if (mark->wp)
+                               waypt_free(mark->wp);
+                       free_mark(mark);
                }
-               prev_mark = mark;
-               mark = mark->next;
        }
 }
 
@@ -335,27 +384,27 @@ ce_remove_unused_marks(void)
 void
 ce_print_results(void)
 {
-       ce_route *curr_route = routes;
-       while (curr_route != NULL) {
-               printf("Route name=%s id=%s\n", curr_route->r->rte_name, curr_route->id);
-               ce_mark *curr_mark = curr_route->marks;
-               while (curr_mark != NULL) {
-                       if (curr_mark->wp == NULL)
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               queue *elem2, *tmp2;
+               ce_route *route = (ce_route *) elem;
+               printf("Route name=%s id=%s\n", route->r->rte_name, route->id);
+               QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) {
+                       ce_mark *mark = (ce_mark *) elem2;
+                       if (mark->wp == NULL)
                                printf("  null\n");
                        else
-                               printf("  %s (%f, %f)\n", curr_mark->wp->shortname, curr_mark->wp->latitude, curr_mark->wp->longitude);
-                       curr_mark = curr_mark->next;
+                               printf("  %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude);
                }
-               curr_route = curr_route->next;
        }
-       ce_mark *curr_mark = marks;
-       while (curr_mark != NULL) {
-               printf("Mark name=%s id=%s ", curr_mark->wp->shortname, curr_mark->id);
-               if (curr_mark->wp == NULL)
+
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id);
+               if (mark->wp == NULL)
                        printf("(null)\n");
                else
-                       printf("(%f, %f)\n", curr_mark->wp->latitude, curr_mark->wp->longitude);
-               curr_mark = curr_mark->next;
+                       printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude);
        }
 }
 
@@ -363,37 +412,48 @@ ce_print_results(void)
 void
 ce_rd_deinit(void)
 {
+       queue *elem, *tmp;
+
        ce_fix_waypoints();
        ce_check_route_names();
        ce_remove_unused_marks();
        // ce_print_results();
 
        // Add routes to GPSBabel
-       ce_route *route = routes;
-       while (route != NULL) {
+       QUEUE_FOR_EACH(&ce_route_head, elem, tmp) {
+               ce_route *route = (ce_route *) elem;
+               queue *elem2, *tmp2;
                route_add_head(route->r);
-               ce_mark *mark = route->marks;
-               while (mark->next != NULL) {
-                       route_add_wpt(route->r, mark->wp);
-                       mark = mark->next;
+               QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) {
+                       ce_mark *mark = (ce_mark *) elem2;
+                       if (mark->wp)
+                               route_add_wpt(route->r, mark->wp);
+                       else
+                               printf("Undefined mark: %s\n", mark->id);
                }
-               route = route->next;
+               free_route(route);
        }
 
        // Add (unused) marks to GPSBabel
-       ce_mark *mark = marks;
-       while (mark != NULL) {
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
                waypt_add(mark->wp);
-               mark = mark->next;
+               free_mark(mark);
        }
 
        fclose(fd);
+       xfree(element);
+       xfree(cdatastr);
 }
 
 void
 ce_wr_init(const char *fname)
 {
-       fatal(MYNAME ": Does not support writing CoastalExplorer files.\n");
+       mkshort_handle = mkshort_new_handle();
+       QUEUE_INIT(&ce_mark_head);
+       time_buffer = xcalloc(MY_TBUF,1);
+       uuid_buffer = xcalloc(MY_UBUF,1);
+
        ofd = xfopen(fname, "w", MYNAME);
 }
 
@@ -401,11 +461,112 @@ void
 ce_wr_deinit(void)
 {
        fclose(ofd);
+       mkshort_del_handle(mkshort_handle);
+       xfree(time_buffer);
+       xfree(uuid_buffer);
+}
+
+static char *
+ce_gen_creation_time(time_t tm)
+{
+       struct tm *t = localtime(&tm);
+       sprintf(time_buffer, "%04d%02d%02dT%02d%02d%02dZ", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+       return time_buffer;
+}
+
+static char *
+ce_gen_current_time(void)
+{
+       return ce_gen_creation_time(current_time());
+}
+
+static char *
+ce_gen_uuid(void)
+{
+       uuid_t uu;
+       uuid_generate(uu);
+       sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7],
+               uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
+       return uuid_buffer;
+}
+
+static void
+ce_route_hdr(const route_head *rte)
+{
+       fprintf(ofd, "\t<Route created=\"%s\" id=\"{%s}\">\n", ce_gen_current_time(), ce_gen_uuid());
+       fprintf(ofd, "\t\t<Marks>\n");
+}
+
+static void
+ce_route_disp(const waypoint *waypointp)
+{
+       char *uuid = ce_gen_uuid();
+       char *id = xcalloc(strlen(uuid)+3, 1);
+       sprintf(id, "{%s}", uuid);
+       currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1);
+       currentMark->id = id;
+       currentMark->wp = (waypoint *) waypointp;
+       ENQUEUE_TAIL(&ce_mark_head, &currentMark->Q);
+       fprintf(ofd, "\t\t\t%s\n", id);
+}
+
+static void
+ce_route_tlr(const route_head *rte)
+{
+       fprintf(ofd, "\t\t</Marks>\n");
+       if (rte->rte_name)
+               fprintf(ofd, "\t\t<Name>%s</Name>\n", rte->rte_name);
+       fprintf(ofd, "\t</Route>\n");
+}
+
+static void
+ce_waypt_pr(const waypoint *waypointp)
+{
+}
+
+static void
+ce_mark_pr(void)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) {
+               ce_mark *mark = (ce_mark *) elem;
+               double latitude = mark->wp->latitude;
+               char NorS = 'N';
+               char EorW = 'E';
+               double longitude = mark->wp->longitude;
+               fprintf(ofd, "\t<Mark created=\"%s\" id=\"%s\">\n", ce_gen_creation_time(mark->wp->creation_time), mark->id);
+               if (latitude < 0) {
+                       latitude = -latitude;
+                       NorS = 'S';
+               }
+               if (longitude < 0) {
+                       longitude = -longitude;
+                       EorW = 'W';
+               }
+               fprintf(ofd, "\t\t<Position>%3.6f %c %3.6f %c</Position>\n", latitude, NorS, longitude, EorW);
+               if (mark->wp->shortname)
+                       fprintf(ofd, "\t\t<Name>%s</Name>\n", mark->wp->shortname);
+               fprintf(ofd, "\t</Mark>\n");
+               free_mark(mark);
+       }
 }
 
 void
 ce_write(void)
 {
+       setshort_whitespace_ok(mkshort_handle, 0);
+       setshort_length(mkshort_handle, 32);
+
+       fprintf(ofd, "<?xml version=\"1.0\"?>\n");
+       fprintf(ofd, "<NavObjectCollection created=\"%s\"\n", ce_gen_current_time());
+       fprintf(ofd, "\t<Name>Navigation Objects</Name>\n");
+
+       route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp);
+       ce_mark_pr();
+       waypt_disp_all(ce_waypt_pr);
+
+       fprintf(ofd, "</NavObjectCollection>\n");
 }
 
 ff_vecs_t coastexp_vecs = {
index 24568428bb2ca73c43f693e0759c6ee7e66ee528..bdbfaa07f720c7b2e50b7190676443a060d89268 100755 (executable)
@@ -8,141 +8,169 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
 <time>1970-01-01T00:00:00Z</time>
 <bounds minlat="34.019184000" minlon ="-122.441589000" maxlat="37.229349000" maxlon="-120.438209000" />
 <wpt lat="37.229349000" lon="-122.441589000">
+<time>2004-11-06T05:13:00Z</time>
   <name>PESCDR01</name>
   <cmt>PESCDR01</cmt>
   <desc>PESCDR01</desc>
 </wpt>
 <wpt lat="37.183397000" lon="-122.411904000">
+<time>2004-11-06T05:13:24Z</time>
   <name>PIGEON01</name>
   <cmt>PIGEON01</cmt>
   <desc>PIGEON01</desc>
 </wpt>
 <wpt lat="37.090736000" lon="-122.348775000">
+<time>2004-11-06T05:13:41Z</time>
   <name>ANONUV01</name>
   <cmt>ANONUV01</cmt>
   <desc>ANONUV01</desc>
 </wpt>
 <wpt lat="36.929502000" lon="-122.113725000">
+<time>2004-11-06T05:14:09Z</time>
   <name>SCRUZ01</name>
   <cmt>SCRUZ01</cmt>
   <desc>SCRUZ01</desc>
 </wpt>
 <wpt lat="36.934235000" lon="-122.022130000">
+<time>2004-11-06T05:14:16Z</time>
   <name>SCRUZ02</name>
   <cmt>SCRUZ02</cmt>
   <desc>SCRUZ02</desc>
 </wpt>
 <wpt lat="36.960666000" lon="-122.024734000">
+<time>2004-11-06T05:14:20Z</time>
   <name>SCRUZENT</name>
   <cmt>SCRUZENT</cmt>
   <desc>SCRUZENT</desc>
 </wpt>
 <wpt lat="36.581344000" lon="-121.995411000">
+<time>2004-11-06T05:24:22Z</time>
   <name>CYPRSSPT</name>
   <cmt>CYPRSSPT</cmt>
   <desc>CYPRSSPT</desc>
 </wpt>
 <wpt lat="36.301110000" lon="-121.919097000">
+<time>2004-11-06T05:24:38Z</time>
   <name>PTSUR</name>
   <cmt>PTSUR</cmt>
   <desc>PTSUR</desc>
 </wpt>
 <wpt lat="36.238177000" lon="-121.855209000">
+<time>2004-11-06T05:25:15Z</time>
   <name>COOPERPT</name>
   <cmt>COOPERPT</cmt>
   <desc>COOPERPT</desc>
 </wpt>
 <wpt lat="36.225175000" lon="-121.801314000">
+<time>2004-11-06T05:25:26Z</time>
   <name>PFEIFENT</name>
   <cmt>PFEIFENT</cmt>
   <desc>PFEIFENT</desc>
 </wpt>
 <wpt lat="36.230449000" lon="-121.797444000">
+<time>2004-11-06T05:25:31Z</time>
   <name>PFEIFANC</name>
   <cmt>PFEIFANC</cmt>
   <desc>PFEIFANC</desc>
 </wpt>
 <wpt lat="35.879801000" lon="-121.498947000">
+<time>2004-11-06T05:28:26Z</time>
   <name>SANMRT01</name>
   <cmt>SANMRT01</cmt>
   <desc>SANMRT01</desc>
 </wpt>
 <wpt lat="35.652801000" lon="-121.308485000">
+<time>2004-11-06T05:28:33Z</time>
   <name>PDRSBLNC</name>
   <cmt>PDRSBLNC</cmt>
   <desc>PDRSBLNC</desc>
 </wpt>
 <wpt lat="35.623297000" lon="-121.185920000">
+<time>2004-11-06T05:28:50Z</time>
   <name>SNSMNENT</name>
   <cmt>SNSMNENT</cmt>
   <desc>SNSMNENT</desc>
 </wpt>
 <wpt lat="35.640478000" lon="-121.183772000">
+<time>2004-11-06T05:28:53Z</time>
   <name>SNSMNANC</name>
   <cmt>SNSMNANC</cmt>
   <desc>SNSMNANC</desc>
 </wpt>
 <wpt lat="35.572353000" lon="-121.152797000">
+<time>2004-11-06T05:36:18Z</time>
   <name>CAMBRIA</name>
   <cmt>CAMBRIA</cmt>
   <desc>CAMBRIA</desc>
 </wpt>
 <wpt lat="35.449214000" lon="-121.020825000">
+<time>2004-11-06T05:36:26Z</time>
   <name>PTESTERO</name>
   <cmt>PTESTERO</cmt>
   <desc>PTESTERO</desc>
 </wpt>
 <wpt lat="35.216602000" lon="-120.928391000">
+<time>2004-11-06T05:36:35Z</time>
   <name>PTBUCHON</name>
   <cmt>PTBUCHON</cmt>
   <desc>PTBUCHON</desc>
 </wpt>
 <wpt lat="34.883361000" lon="-120.684631000">
+<time>2004-11-06T05:36:42Z</time>
   <name>PTSAL01</name>
   <cmt>PTSAL01</cmt>
   <desc>PTSAL01</desc>
 </wpt>
 <wpt lat="34.884641000" lon="-120.652026000">
+<time>2004-11-06T05:36:47Z</time>
   <name>PTSALENT</name>
   <cmt>A description of the Point Sal Entrance mark</cmt>
   <desc>A description of the Point Sal Entrance mark</desc>
 </wpt>
 <wpt lat="34.896555000" lon="-120.649124000">
+<time>2004-11-06T05:37:04Z</time>
   <name>PTSALANC</name>
   <cmt>PTSALANC</cmt>
   <desc>PTSALANC</desc>
 </wpt>
 <wpt lat="34.758180000" lon="-120.642516000">
+<time>2004-11-06T05:39:49Z</time>
   <name>PURSMAPT</name>
   <cmt>PURSMAPT</cmt>
   <desc>PURSMAPT</desc>
 </wpt>
 <wpt lat="34.572579000" lon="-120.663636000">
+<time>2004-11-06T05:39:54Z</time>
   <name>PTARGLLO</name>
   <cmt>PTARGLLO</cmt>
   <desc>PTARGLLO</desc>
 </wpt>
 <wpt lat="34.113844000" lon="-120.492630000">
+<time>2004-11-06T05:40:05Z</time>
   <name>SANMGL01</name>
   <cmt>SANMGL01</cmt>
   <desc>SANMGL01</desc>
 </wpt>
 <wpt lat="34.029483000" lon="-120.471409000">
+<time>2004-11-06T05:40:44Z</time>
   <name>SANMGL02</name>
   <cmt>SANMGL02</cmt>
   <desc>SANMGL02</desc>
 </wpt>
 <wpt lat="34.019184000" lon="-120.444197000">
+<time>2004-11-06T05:40:48Z</time>
   <name>SANMGL03</name>
   <cmt>SANMGL03</cmt>
   <desc>SANMGL03</desc>
 </wpt>
 <wpt lat="34.023478000" lon="-120.438209000">
+<time>2004-11-06T05:40:57Z</time>
   <name>ADCOVENT</name>
   <cmt>ADCOVENT</cmt>
   <desc>ADCOVENT</desc>
 </wpt>
 <wpt lat="34.028615000" lon="-120.439696000">
+<time>2004-11-06T05:40:59Z</time>
   <name>ADCOVANC</name>
   <cmt>ADCOVANC</cmt>
   <desc>ADCOVANC</desc>
@@ -150,31 +178,44 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/
 <rte>
   <name>Into The Bay</name>
   <rtept lat="37.763290" lon="-122.282580">
+<time>2004-11-06T01:09:09Z</time>
     <name>SFBALBAY</name>
   </rtept>
   <rtept lat="37.751613" lon="-122.339028">
+<time>2004-11-06T01:09:10Z</time>
     <name>SFBAY001</name>
   </rtept>
   <rtept lat="37.817420" lon="-122.394305">
+<time>2004-11-06T01:09:13Z</time>
     <name>SFBAY002</name>
   </rtept>
   <rtept lat="37.819339" lon="-122.478302">
+<time>2004-11-06T01:09:16Z</time>
     <name>SFGGBRDG</name>
   </rtept>
   <rtept lat="37.773033" lon="-122.605838">
+<time>2004-11-06T01:09:20Z</time>
     <name>SFCHNL01</name>
   </rtept>
   <rtept lat="37.518860" lon="-122.529914">
+<time>2004-11-06T01:09:26Z</time>
     <name>HMCOLREF</name>
   </rtept>
   <rtept lat="37.482348" lon="-122.507704">
+<time>2004-11-06T01:09:27Z</time>
     <name>HMPILL01</name>
   </rtept>
   <rtept lat="37.475062" lon="-122.488531">
+<time>2004-11-06T05:16:24Z</time>
     <name>HMPILLPT</name>
   </rtept>
   <rtept lat="37.476448" lon="-122.475800">
+<time>2004-11-06T01:09:29Z</time>
     <name>HMPILL02</name>
   </rtept>
+  <rtept lat="37.495102" lon="-122.483927">
+<time>2004-11-06T01:09:30Z</time>
+    <name>HMPILL03</name>
+  </rtept>
 </rte>
 </gpx>
index 82658b27cf5a27c6f4c33f3d78448d61a791493c..cd772eead21b36e4f92cad954e18b891448770f1 100755 (executable)
@@ -407,6 +407,18 @@ ${PNAME} -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx
 compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref
 #
 
+#
+# CoastalExplorer..
+${PNAME} -r -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx
+compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref
+${PNAME} -r -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob
+compare ${TMPDIR}/coastexp.nob reference/coastexp.ref2
+${PNAME} -w -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx
+compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref3
+${PNAME} -w -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob
+compare ${TMPDIR}/coastexp.nob reference/coastexp.ref4
+#
+
 # PsiTrex.  A text format that can't be handled by XCSV due to context of
 # data based on other data values in the file
 # Waypoints first
index 770362ef6818bbae5c330056a829111cd1096bc0..14e254bbf24988d80dd9a78402fdceb1c5bc64e2 100644 (file)
@@ -36,6 +36,12 @@ static xg_tag_mapping *xg_tag_tbl;
 
 #define MYNAME "XML Reader"
 
+void
+write_xml_header(FILE *ofd)
+{
+       fprintf(ofd, "<?xml version=\"1.0\"?>\n");
+}
+
 void
 write_xml_entity(FILE *ofd, const char *indent,
                  const char *tag, const char *value)
@@ -53,6 +59,37 @@ write_optional_xml_entity(FILE *ofd, const char *indent,
                 write_xml_entity(ofd, indent, tag, value);
 }
 
+void
+write_xml_entity_begin0(FILE *ofd, const char *indent,
+                                                         const char *tag)
+{
+    fprintf(ofd, "%s<%s>\n", indent, tag);
+}
+
+void
+write_xml_entity_begin1(FILE *ofd, const char *indent,
+                                                         const char *tag, const char *attr,
+                                                         const char *attrval)
+{
+    fprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval);
+}
+
+void
+write_xml_entity_begin2(FILE *ofd, const char *indent,
+                                                         const char *tag, const char *attr1,
+                                                         const char *attrval1, const char *attr2,
+                                                         const char *attrval2)
+{
+    fprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2);
+}
+
+void
+write_xml_entity_end(FILE *ofd, const char *indent,
+                                        const char *tag)
+{
+    fprintf(ofd, "%s</%s>\n", indent, tag);
+}
+
 void
 xml_write_time(FILE *ofd, const time_t timep, char *elname)
 {